package handler

import (
	"net/http"
	"path/filepath"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"markedit/internal/model"
	"markedit/internal/service"
)

type FileHandler struct {
	fileService *service.FileService
	logger      *logrus.Logger
}

func NewFileHandler(fileService *service.FileService, logger *logrus.Logger) *FileHandler {
	return &FileHandler{
		fileService: fileService,
		logger:      logger,
	}
}

// CreateDocument 创建新文档
// @Summary 创建新文档
// @Description 创建一个新的Markdown文档
// @Tags 文件管理
// @Accept json
// @Produce json
// @Param document body model.Document true "文档信息"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/files/documents [post]
func (h *FileHandler) CreateDocument(c *gin.Context) {
	var doc model.Document
	if err := c.ShouldBindJSON(&doc); err != nil {
		h.logger.Errorf("Failed to bind document: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	// 验证文档数据
	if doc.Name == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Validation failed",
			Message: "Document name is required",
		})
		return
	}

	// 创建文档
	createdDoc, err := h.fileService.CreateDocument(doc.Title, doc.Content, doc.FolderID)
	if err != nil {
		h.logger.Errorf("Failed to create document: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to create document",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("Document created: %s", createdDoc.ID)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    createdDoc,
		Message: "Document created successfully",
	})
}

// GetDocument 获取文档
// @Summary 获取文档
// @Description 根据ID获取文档详情
// @Tags 文件管理
// @Produce json
// @Param id path string true "文档ID"
// @Success 200 {object} model.APIResponse
// @Failure 404 {object} model.ErrorResponse
// @Router /api/files/documents/{id} [get]
func (h *FileHandler) GetDocument(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Document ID is required",
		})
		return
	}

	doc, err := h.fileService.GetDocument(id)
	if err != nil {
		h.logger.Errorf("Failed to get document %s: %v", id, err)
		c.JSON(http.StatusNotFound, model.ErrorResponse{
			Error:   "Document not found",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    doc,
		Message: "Document retrieved successfully",
	})
}

// UpdateDocument 更新文档
// @Summary 更新文档
// @Description 更新文档内容和元数据
// @Tags 文件管理
// @Accept json
// @Produce json
// @Param id path string true "文档ID"
// @Param document body model.Document true "文档信息"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/files/documents/{id} [put]
func (h *FileHandler) UpdateDocument(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Document ID is required",
		})
		return
	}

	var doc model.Document
	if err := c.ShouldBindJSON(&doc); err != nil {
		h.logger.Errorf("Failed to bind document: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	doc.ID = id
	updatedDoc, err := h.fileService.UpdateDocument(id, doc.Title, doc.Content)
	if err != nil {
		h.logger.Errorf("Failed to update document %s: %v", id, err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to update document",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("Document updated: %s", id)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    updatedDoc,
		Message: "Document updated successfully",
	})
}

// DeleteDocument 删除文档
// @Summary 删除文档
// @Description 删除指定的文档
// @Tags 文件管理
// @Produce json
// @Param id path string true "文档ID"
// @Success 200 {object} model.APIResponse
// @Failure 404 {object} model.ErrorResponse
// @Router /api/files/documents/{id} [delete]
func (h *FileHandler) DeleteDocument(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Document ID is required",
		})
		return
	}

	err := h.fileService.DeleteDocument(id)
	if err != nil {
		h.logger.Errorf("Failed to delete document %s: %v", id, err)
		c.JSON(http.StatusNotFound, model.ErrorResponse{
			Error:   "Failed to delete document",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("Document deleted: %s", id)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    nil,
		Message: "Document deleted successfully",
	})
}

// ListDocuments 列出文档
// @Summary 列出文档
// @Description 获取文档列表，支持分页和过滤
// @Tags 文件管理
// @Produce json
// @Param folder_id query string false "文件夹ID"
// @Param page query int false "页码" default(1)
// @Param limit query int false "每页数量" default(20)
// @Param search query string false "搜索关键词"
// @Success 200 {object} model.APIResponse
// @Router /api/files/documents [get]
func (h *FileHandler) ListDocuments(c *gin.Context) {
	folderID := c.Query("folder_id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20"))
	search := c.Query("search")

	if page < 1 {
		page = 1
	}
	if limit < 1 || limit > 100 {
		limit = 20
	}

	allDocs, err := h.fileService.ListDocuments(folderID)
	if err != nil {
		h.logger.Errorf("Failed to list documents: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to list documents",
			Message: err.Error(),
		})
		return
	}

	// 如果有搜索关键词，进行搜索过滤
	var docs []*model.Document
	if search != "" {
		searchResults, err := h.fileService.SearchDocuments(search)
		if err != nil {
			h.logger.Errorf("Failed to search documents: %v", err)
			c.JSON(http.StatusInternalServerError, model.ErrorResponse{
				Error:   "Failed to search documents",
				Message: err.Error(),
			})
			return
		}
		docs = searchResults
	} else {
		docs = allDocs
	}

	// 手动实现分页
	total := len(docs)
	start := (page - 1) * limit
	end := start + limit
	if start > total {
		start = total
	}
	if end > total {
		end = total
	}
	
	if start < end {
		docs = docs[start:end]
	} else {
		docs = []*model.Document{}
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"documents": docs,
			"total":     total,
			"page":      page,
			"limit":     limit,
		},
		Message: "Documents retrieved successfully",
	})
}

// CreateFolder 创建文件夹
// @Summary 创建文件夹
// @Description 创建一个新的文件夹
// @Tags 文件管理
// @Accept json
// @Produce json
// @Param folder body model.Folder true "文件夹信息"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/files/folders [post]
func (h *FileHandler) CreateFolder(c *gin.Context) {
	var folder model.Folder
	if err := c.ShouldBindJSON(&folder); err != nil {
		h.logger.Errorf("Failed to bind folder: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	if folder.Name == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Validation failed",
			Message: "Folder name is required",
		})
		return
	}

	createdFolder, err := h.fileService.CreateFolder(folder.Name, folder.ParentID)
	if err != nil {
		h.logger.Errorf("Failed to create folder: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to create folder",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("Folder created: %s", createdFolder.ID)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    createdFolder,
		Message: "Folder created successfully",
	})
}

// GetFolder 获取文件夹
// @Summary 获取文件夹
// @Description 根据ID获取文件夹详情
// @Tags 文件管理
// @Produce json
// @Param id path string true "文件夹ID"
// @Success 200 {object} model.APIResponse
// @Failure 404 {object} model.ErrorResponse
// @Router /api/files/folders/{id} [get]
func (h *FileHandler) GetFolder(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Folder ID is required",
		})
		return
	}

	folder, err := h.fileService.GetFolder(id)
	if err != nil {
		h.logger.Errorf("Failed to get folder %s: %v", id, err)
		c.JSON(http.StatusNotFound, model.ErrorResponse{
			Error:   "Folder not found",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    folder,
		Message: "Folder retrieved successfully",
	})
}

// ListFolders 列出文件夹
// @Summary 列出文件夹
// @Description 获取文件夹列表
// @Tags 文件管理
// @Produce json
// @Param parent_id query string false "父文件夹ID"
// @Success 200 {object} model.APIResponse
// @Router /api/files/folders [get]
func (h *FileHandler) ListFolders(c *gin.Context) {
	parentID := c.Query("parent_id")

	folders, err := h.fileService.ListFolders(parentID)
	if err != nil {
		h.logger.Errorf("Failed to list folders: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to list folders",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    folders,
		Message: "Folders retrieved successfully",
	})
}

// DeleteFolder 删除文件夹
// @Summary 删除文件夹
// @Description 删除指定的文件夹
// @Tags 文件管理
// @Produce json
// @Param id path string true "文件夹ID"
// @Success 200 {object} model.APIResponse
// @Failure 404 {object} model.ErrorResponse
// @Router /api/files/folders/{id} [delete]
func (h *FileHandler) DeleteFolder(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Folder ID is required",
		})
		return
	}

	err := h.fileService.DeleteFolder(id)
	if err != nil {
		h.logger.Errorf("Failed to delete folder %s: %v", id, err)
		c.JSON(http.StatusNotFound, model.ErrorResponse{
			Error:   "Failed to delete folder",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("Folder deleted: %s", id)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    nil,
		Message: "Folder deleted successfully",
	})
}

// UploadFile 上传文件
// @Summary 上传文件
// @Description 上传文件到指定文件夹
// @Tags 文件管理
// @Accept multipart/form-data
// @Produce json
// @Param file formData file true "文件"
// @Param folder_id formData string false "文件夹ID"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/files/upload [post]
func (h *FileHandler) UploadFile(c *gin.Context) {
	file, header, err := c.Request.FormFile("file")
	if err != nil {
		h.logger.Errorf("Failed to get uploaded file: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "No file uploaded",
			Message: err.Error(),
		})
		return
	}
	defer file.Close()

	folderID := c.PostForm("folder_id")

	// 验证文件类型
	ext := filepath.Ext(header.Filename)
	allowedExts := []string{".md", ".txt", ".jpg", ".png", ".gif", ".svg"}
	allowed := false
	for _, allowedExt := range allowedExts {
		if ext == allowedExt {
			allowed = true
			break
		}
	}

	if !allowed {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "File type not allowed",
			Message: "Only .md, .txt, .jpg, .png, .gif, .svg files are allowed",
		})
		return
	}

	// 处理文件上传
	fileInfo, err := h.fileService.UploadFile(file, header, folderID)
	if err != nil {
		h.logger.Errorf("Failed to upload file: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to upload file",
			Message: err.Error(),
		})
		return
	}

	h.logger.Infof("File uploaded: %s", fileInfo.Name)
	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    fileInfo,
		Message: "File uploaded successfully",
	})
}

// SearchDocuments 搜索文档
// @Summary 搜索文档
// @Description 根据关键词搜索文档
// @Tags 文件管理
// @Produce json
// @Param q query string true "搜索关键词"
// @Param page query int false "页码" default(1)
// @Param limit query int false "每页数量" default(20)
// @Success 200 {object} model.APIResponse
// @Router /api/files/search [get]
func (h *FileHandler) SearchDocuments(c *gin.Context) {
	query := c.Query("q")
	if query == "" {
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid parameter",
			Message: "Search query is required",
		})
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20"))

	if page < 1 {
		page = 1
	}
	if limit < 1 || limit > 100 {
		limit = 20
	}

	allResults, err := h.fileService.SearchDocuments(query)
	if err != nil {
		h.logger.Errorf("Failed to search documents: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Search failed",
			Message: err.Error(),
		})
		return
	}

	// 手动实现分页
	total := len(allResults)
	start := (page - 1) * limit
	end := start + limit

	if start >= total {
		start = total
	}
	if end > total {
		end = total
	}

	var results []*model.Document
	if start < total {
		results = allResults[start:end]
	} else {
		results = []*model.Document{}
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"results": results,
			"total":   total,
			"page":    page,
			"limit":   limit,
			"query":   query,
		},
		Message: "Search completed successfully",
	})
}